﻿using blackhouse.BlackApart.Business;
using blackhouse.BlackApart.Business.Reservations;
using blackhouse.Data;
using blackhouse;
using Quartz;
using System;
using System.Collections.Generic;
using System.Configuration;
using System.Data;
using System.Linq;
using System.Web;

namespace blackhouse.StareKino.QuartzActions {
    public class ReservationClientMailAction : IJob {

        #region Fields

        private MsSqlAdoDataHelper dataHelper;
        private Factory factory = Factory.Instance();

        #endregion

        #region Constructors

        public ReservationClientMailAction() {
            this.dataHelper = new MsSqlAdoDataHelper(ConfigurationManager.AppSettings["MSSQLConnectionString"]);
        }

        #endregion

        #region Methods

        public void Execute(IJobExecutionContext context) {
            DbData[] mailsToSend = this.GetMailsToSend();
            foreach (DbData data in mailsToSend) {
                if (this.AddMailToSend(data))
                    this.MarkActionAsComplete(data.ActionId);
                else
                    this.MarkActionAsSendLater(data.ActionId);
            }
        }

        private bool AddMailToSend(DbData data) {
            IWebReservation reservation = this.factory.GetWebReservation(data.ReservationId);
            if (reservation.Client == null || !reservation.Client.EMail.IsValidEmail()) return false;
            ReservationClientMailActionData mailData = new ReservationClientMailActionData(reservation.ReservationId);
            try {
                blackhouse.AsyncMail.Web.SendMail sendMail = new AsyncMail.Web.SendMail(data.DefaultMailTitle, mailData, data.TemplateId);
                sendMail.SendTo(reservation.Client.EMail, reservation.Client.FirstName + " " + reservation.Client.LastName);
                if (!String.IsNullOrEmpty(data.AdditionalRecipient)) {
                    foreach (string addMail in data.AdditionalRecipient.Split(';')) {
                        if (addMail.IsValidEmail())
                            sendMail.SendTo(addMail, addMail);
                    }
                }
            }
            catch (Exception e) { return false; }
            return true;
        }

        private DbData[] GetMailsToSend() {
            this.dataHelper.Reset();
            this.dataHelper.ProcedureName = "bhp_ReservationMailGetToSend";
            IDataReader reader = this.dataHelper.Execute();
            List<DbData> data = new List<DbData>();
            while (reader.Read()) {
                DbData dataItem = new DbData();
                dataItem.ActionId = Convert.ToInt32(reader["ActionId"]);
                dataItem.ReservationId = Convert.ToInt32(reader["ReservationId"]);
                dataItem.TemplateId = Convert.ToInt32(reader["TemplateId"]);
                dataItem.TemplateName = Convert.ToString(reader["Name"]);
                dataItem.DefaultMailTitle = Convert.ToString(reader["DefaultMailTitle"]);
                if (!reader.IsDBNull(reader.GetOrdinal("AdditionalRecipient")))
                    dataItem.AdditionalRecipient = Convert.ToString(reader["AdditionalRecipient"]);
                data.Add(dataItem);
            }
            return data.ToArray();
        }

        private void MarkActionAsComplete(int actionId) {
            this.dataHelper.Reset();
            this.dataHelper.ProcedureName = "bhp_ReservationMailComplete";
            this.dataHelper.AddParameter("ActionId", actionId, DbType.Int32);
            this.dataHelper.ExecuteWithoutResult();
        }

        private void MarkActionAsSendLater(int actionId) {
            this.dataHelper.Reset();
            this.dataHelper.ProcedureName = "bhp_ReservationMailLeaveExecuteForMin";
            this.dataHelper.AddParameter("ActionId", actionId, DbType.Int32);
            this.dataHelper.ExecuteWithoutResult();
        }

        #endregion

        #region Internal

        private struct DbData {
            public int ActionId;
            public int ReservationId;
            public int TemplateId;
            public string TemplateName;
            public string DefaultMailTitle;
            public string AdditionalRecipient;
        }

        #endregion

    }

    [Serializable]
    public class ReservationClientMailActionData {

        public int ReservationId { get; set; }

        public ReservationClientMailActionData() { }

        public ReservationClientMailActionData(int reservationId) {
            this.ReservationId = reservationId;
        }

    }

}